<!--
 * @Date: 2023-03-16 13:47:41
 * @LastEditors: Zireael 1193875164@qq.com
 * @LastEditTime: 2023-04-10 21:15:57
 * @FilePath: \A19\frontend\src\components\RunCode\PlayGround.vue
-->
<template>
  <div class="container">
    <div class="title">PlayGround</div>
    <div class="con ver">
      <div class="e-box">
        <div class="select">
          <el-select v-model="language" @change="changeLanguage" size="large">
            <el-option v-for="lan in lans" :key="lan" :value="lan">{{ lan }}</el-option>
          </el-select>
        </div>
        <div id="codeEditBox"></div>
        <div class="submit">
          <el-button type="primary" @click="submitCode" :loading="loading"
            >运行</el-button
          >
        </div>
      </div>
      <div class="bottom-container">
        <div class="sub-box">
          <span
            @click="switchPanel(true)"
            class="select-plane"
            :style="{}"
            :class="{ 'on-panel': inputing }"
            >输入
          </span>
          <span
            @click="switchPanel(false)"
            class="select-plane"
            :style="{}"
            :class="{ 'on-panel': !inputing }"
            >输出</span
          >
          <!-- <span @click="open" class="btn"><el-icon><ArrowUpBold v-if="!test" /><ArrowDownBold v-else /></el-icon></span> -->
        </div>
        <div class="msg" :style="{ height: '200px' }">
          <ElInput
            v-model="stdin"
            v-if="inputing"
            class="textarea"
            type="textarea"
          ></ElInput>
          <div class="out" v-else>
            {{ msg }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
import EditorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import { nextTick, ref } from "vue";
import * as monaco from "monaco-editor";
import { useClientStore } from "../../pinia/stores/client";

const { client } = useClientStore();
let loadingInstance: any = ElLoading.service({
  target: ".container",
});
const loading = ref(false);
const lans = ['cpp', 'rust', 'python3', 'go', 'javascript', 'java', 'C#','php']
const language = ref("cpp");
const text = ref("");
const stdin = ref("");
const msg = ref("");
const changeLanguage = () => {
  const model = editor.getModel();
  if (model) monaco.editor.setModelLanguage(model, language.value);
};

self.MonacoEnvironment = {
  getWorker(_: string, label: string) {
    if (label === "json") {
      return new jsonWorker();
    }
    if (label === "css" || label === "scss" || label === "less") {
      return new cssWorker();
    }
    if (label === "html" || label === "handlebars" || label === "razor") {
      return new htmlWorker();
    }
    if (["typescript", "javascript"].includes(label)) {
      return new tsWorker();
    }
    return new EditorWorker();
  },
};

let editor: monaco.editor.IStandaloneCodeEditor;
const editorInit = () => {
  nextTick(() => {
    monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
      noSemanticValidation: true,
      noSyntaxValidation: false,
    });
    monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
      target: monaco.languages.typescript.ScriptTarget.ES2016,
      allowNonTsExtensions: true,
    });

    !editor
      ? (editor = monaco.editor.create(
          document.getElementById("codeEditBox") as HTMLElement,
          {
            value: text.value,
            language: language.value,
            automaticLayout: true,
            foldingStrategy: "indentation",
            renderLineHighlight: "all",
            selectOnLineNumbers: true,
            minimap: {
              enabled: false,
            },
            readOnly: false,
            fontSize: 16,
            scrollBeyondLastLine: false,
            overviewRulerBorder: false,
          }
        ))
      : editor.setValue("");
    // console.log(editor)
    editor.onDidChangeModelContent((val: any) => {
      text.value = editor.getValue();
    });
    setTimeout(() => {
      loadingInstance.close();
    }, 300);
  });
};
editorInit();

const height = ref(200);
const test = ref(false);
const inputing = ref(false);
const switchPanel = (input: boolean) => {
  inputing.value = input;
};

const submitCode = async () => {
  if (language.value === "不限") return ElMessage.warning("请选择语言");
  loading.value = true;
  //   const ret = await request({
  //     url:'/code/run',
  //     method:'post',
  //     data:{
  //       code:text.value,
  //       type:language.value === 'javascript'?'nodejs':language.value,
  //       stdin:stdin.value
  //     }
  //   })
  //   console.log(ret);
  //   if(ret.data.code === 0){
  //     if(ret.data.data.code === 0){
  //     ElMessage.success('运行成功')
  //       msg.value = ret.data.data.output
  //     }
  //     else if(ret.data.data.code === 2){
  //       ElMessage.warning('暂不支持该语言')
  //     }
  //   }
  //   else if(ret.data.code === 1){
  //     ElMessage.warning('暂不支持该语言')
  //   }
  const ret = await client.callApi("RunCode/RunCode", {
    code: text.value,
    type: language.value === "javascript" ? "nodejs" : language.value,
    stdin: stdin.value,
  });
  if(ret.isSucc){
    if(ret.res.ret.code === 0){
        ElMessage.success('运行成功')
        msg.value = ret.res.ret.output
    }
    else if(ret.res.ret.code === 1){
        ElMessage.warning(ret.res.ret.message)
        msg.value = ret.res.ret.output
    }
    else{
      ElMessage.warning('暂不支持该语言')
      msg.value = ''
    }
  }


  loading.value = false;
  inputing.value = false;
};
</script>
<style scoped lang="less">
.container {
  background-color: #f2f2f2;
  padding: 80px 0;
  padding-bottom: 10px;
  height: 100%;
  width: 100%;
  overflow: auto;
  .title {
    height: 60px;
    width: 100%;
    background-color: white;
    position: fixed;
    top: 0;
    z-index: 10;
    line-height: 60px;
    font-size: 20px;
    font-weight: bold;
    padding: 0 30px;
  }
}
.con {
  position: relative;
  // height: 100%;
  width: 80%;
  margin: 0 auto;
  background-color: #f2f2f2;

  #codeEditBox {
    //  width: 100%;
    // height: 50%;
    height: calc(100% - 104px);
  }

  .select {
    padding: 10px 10px;
    background: white;
  }

  .submit {
    text-align: center;
    padding: 10px 0;
    background-color: white;
  }

  .e-box {
    width: 100%;
    // padding: 10px;
    box-sizing: border-box;
    padding-bottom: 0;
    display: flex;
    // justify-content: space-between;
    box-sizing: border-box;
    flex-direction: column;
    text-align: left;
    height: 70vh;
  }

  .sub-box {
    background-color: #fff;
    box-sizing: border-box;
    flex: 1;
    color: #696868;
    text-align: left;
    height: 36px;
    line-height: 36px;
    position: relative;
    z-index: 1;

    .select-plane {
      display: inline-block;
      // margin: 0 5px;
      cursor: pointer;
      padding: 0 10px;
      border-top-right-radius: 10px;
      border-top-left-radius: 10px;

      position: relative;
    }

    .on-panel {
      border: 1px solid #dcdfe6;

      &::after {
        content: " ";
        position: absolute;
        height: 3px;
        width: 100%;
        left: 0;
        bottom: -2px;
        background: white;
      }
    }

    .btn {
      display: inline-block;
      height: 36px;
      line-height: 36px;
      float: right;
      cursor: pointer;
      width: 80px;
      text-align: center;
    }
  }

  .msg {
    background-color: #f6f6f6;
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
    position: relative;
    z-index: 0;

    //
    .out {
      padding: 5px 11px;
      box-shadow: 0 0 0 1px #dcdfe6 inset;
      background-color: white;
      height: 100%;
      width: 100%;
      border-radius: 4px;
      overflow: auto;
      text-align: left;
      color: #606266;
      line-height: 1.5;
      font-weight: normal;
      font-size: 14px;
    }
  }
}
.ver {
  border-bottom: 0.0625rem solid rgb(226, 232, 240);
  border-top: 0.0625rem solid rgb(226, 232, 240);
}
</style>

<style lang="less">
.textarea {
  height: 100%;

  .el-textarea__inner {
    height: 100% !important;
    border: none !important;
  }
}
</style>
